home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PACKET
/
CBBS60SO.ZIP
/
MBNODES.C
< prev
next >
Wrap
Text File
|
1989-02-05
|
9KB
|
463 lines
/*
* MBNODES.C - 10/22/87 - Grab routes from NET/ROM
* NN port call time file
*/
#include "mb.h"
#if nncmd
#define ntout 3 /* "got all data" timeout */
short nodetime;
PORTS *was;
char *mp;
short nodedone;
/*
* Node definition record.
* One of these for each node found.
*/
#define no_visit 0x01 /* Node has been visited */
#define no_reach 0x02 /* Node can be reached */
#define no_busy 0x08 /* Node was busy */
typedef struct NODE_S
{
char *call; /* Call of this node */
char *name;
byte state; /* "visited" "can be reached" */
byte hops; /* Distance to this node */
struct NODE_S *found; /* Where we were when we found a path to this one */
struct NODE_S *seen; /* Where we were when we found this one */
struct NODE_S *next; /* Next node */
} NODE;
NODE *nodehd;
NODE *nodetl;
int nodecnt;
NODE *path[8];
int np;
/*
* Find a node.
*/
NODE *findnode(cp)
char *cp;
{
register NODE *n;
for (n = nodehd; n isnt NULL; n = n->next) if (match(cp, n->call)) return n;
return NULL;
}
/*
* Find an unvisited node.
* The one with the lowest cost path from the node we are at.
*/
findunode()
{
register int h;
register NODE *n;
/*
* Find node at min hops not yet visited.
*/
if (nodedone) return false;
h = 256;
path[0] = NULL;
for (n = nodehd; n isnt NULL; n = n->next)
{
if (n->state & no_reach) if (!(n->state & no_visit))
if (n->hops < h)
{
h = n->hops;
path[0] = n;
}
}
if (path[0] is NULL) return false;
for (np = 0; np < 7; np++)
{
if (path[np]->found is NULL) return false;
if (path[np]->found is nodehd) return true;
path[np + 1] = path[np]->found;
}
return false;
}
/*
* Add a node.
*/
NODE *addnode(tp)
char *tp;
{
register NODE *n;
register char *cp;
register char *np;
cp = tp;
np = tp;
for (; *tp; tp++) if (*tp is ':')
{
*tp = '\0';
cp = tp + 1;
}
if ((n = findnode(cp)) isnt NULL)
{
if (n->name is NULL) if (np isnt cp)
{
n->name = (char *)mp; mp += (strlen(np) + 1);
strcpy(n->name, np);
}
return n;
}
nodecnt++;
n = (NODE *)mp; mp += sizeof(NODE);
n->call = (char *)mp; mp += (strlen(cp) + 1);
strcpy(n->call, cp);
if (np is cp) n->name = NULL; else
{
n->name = (char *)mp; mp += (strlen(np) + 1);
strcpy(n->name, np);
}
n->state = 0;
n->hops = 255;
n->found = NULL;
n->seen = NULL;
n->next = NULL;
if (nodehd is NULL) nodehd = n; else nodetl->next = n;
nodetl = n;
return n;
}
/*
* Connect to the local NET/ROM node.
*/
clnode()
{
port->mode = remote;
outstr("C "); outstr(nodehd->call); outchar('\n');
waitcmd();
do
{
if (!getit(nodetime))
{
if (!(port->mode & idle)) distnc();
port->mode = idle;
return;
}
}
while (!iscon(port->line));
}
/*
* Connect to a distant node, using NET/ROM.
*/
cnode()
{
register int i;
path[0]->state setbit no_visit;
for (i = np; i >= 0; i--)
{
outstr("C "); outstr(path[i]->call); outchar('\n');
if (getit(path[i]->hops * nodetime))
{
if (!match(port->fld[1], "CONNECTED"))
{
if (!(port->mode & idle)) distnc();
port->mode = idle;
return false;
}
}
else
{
if (!(port->mode & idle)) distnc();
port->mode = idle;
return false;
}
}
return true;
}
/*
* Get the known nodes, links, and paths to them from THIS node.
*/
getnode()
{
register int i;
register int ti;
short base;
short tcnt;
NODE *temp[64];
NODE *via;
fprintf(was->fl, "\nAt Node: %s\n", path[0]->call);
outstr("p\n");
if (!getit(path[0]->hops * nodetime))
{
if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
if (!(port->mode & idle)) distnc();
port->mode = idle;
return false;
}
fprintf(was->fl, "\nParams: %s", port->line);
while (getit(ntout)) fprintf(was->fl, "Params: %s", port->line);
/*
* Get the nodes known to this node.
*/
outstr("n *\n");
/*
* Get line "Nodes ..."
*/
if (!getit(path[0]->hops * nodetime))
{
if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
if (!(port->mode & idle)) distnc();
port->mode = idle;
return false;
}
if (match(port->fld[1], "NODE"))
{
path[0]->state setbit no_busy;
distnc();
port->mode = idle;
return false;
}
/*
* Add known nodes to link table for this node.
* Unknown number. Timeout to decide got 'em all.
*/
tcnt = 0;
if (getit(ntout)) do
{
for (i = 0; i < port->flds; i++)
{
temp[tcnt] = addnode(port->fld[i]);
if (temp[tcnt]->seen is NULL) temp[tcnt]->seen = path[0];
tcnt++;
}
}
while(getit(ntout));
if (port->mode & idle) return false;
/*
* For each target, get the adjacent nodes toward that target.
*/
for (ti = 0; ti < tcnt; ti++)
{
outstr("n "); outstr(temp[ti]->call); outchar('\n');
/*
* Get line "Routes to ..."
*/
if (!getit(path[0]->hops * nodetime))
{
if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
if (!(port->mode & idle)) distnc();
port->mode = idle;
return false;
}
if (!match(port->fld[1], "ROUTES"))
{
while(getit(ntout));
fprintf(was->fl, "*** Node %s missing routes\n", temp[ti]->call);
}
else
{
addnode(port->fld[3]); /* Pick up node name ... */
/*
* Collect all the adjacent node lines.
* Unknown number. Timeout to decide got 'em all.
*/
if (getit(ntout)) do
{
if (*port->fld[0] is '>') base = 1; else base = 0;
if (i = atoi(port->fld[base]))
{
via = addnode(port->fld[base + 3]);
if (via->found is NULL) via->found = path[0];
if (via->hops > path[0]->hops + 1) via->hops = path[0]->hops + 1;
via->state setbit no_reach;
fprintf(was->fl, " To: %-9.9s Via: %s", temp[ti]->call, port->line);
}
}
while(getit(ntout));
}
if (port->mode & idle) return false;
}
return true;
}
/*
* Trace out the NET/ROM routes.
*/
donet()
{
register int i;
register PORTS *new;
NODE *from, *n;
if (port->mode & sysop) { savecmd(); return; }
if ((new = findport(*port->fld[1])) is NULL) { prtx(mnport); return; }
if ((port->fl = fopen(port->fld[4], "w")) is NULL)
{ nofile(port->fld[4]); return; }
nodecnt = 0;
nodehd = NULL; nodetl = NULL;
mp = tmp->scr;
nodetime = atoi(port->fld[3]);
/*
* Put the local node into the node table.
*/
addnode(port->fld[2]);
nodehd->state setbit no_reach; /* Local node is reachable */
nodehd->state setbit no_visit;
nodehd->hops = 1;
nodehd->found = nodehd;
nodehd->seen = nodehd;
/*
* Remember current port.
*/
was = port;
ioport(new);
/*
* Visit the local node.
*/
nodedone = false;
path[0] = nodehd;
clnode();
if (port->mode & idle) { ioport(was); fclose(was->fl); return; }
getnode();
distnc();
port->mode = idle;
/*
* Visit all nodes the local node knows about.
*/
while (findunode())
{
clnode();
if (!(port->mode & idle))
{
if (cnode()) getnode();
distnc();
port->mode = idle;
}
}
/*
* Put us back on the port we were on when we got here.
*/
ioport(was);
/*
* Now we have all the data, print it.
*/
curtim();
fprintf(was->fl, "\n Data collected at %s %s\n\n", l_date, l_time);
for (n = nodehd; n isnt NULL; n = n->next)
{
if (n->name is NULL)
fprintf(was->fl, "Node: %-9.9s, No Alias, %3d hops, seen at %s",
n->call, n->hops, n->seen->call);
else
fprintf(was->fl, "Node: %-9.9s, Alias %-6.6s, %3d hops, seen at %s",
n->call, n->name, n->hops, n->seen->call);
if (!(n->state & no_reach)) fprintf(was->fl, " (Not reachable)");
if (n->state & no_busy) fprintf(was->fl, " (Was busy)");
fprintf(was->fl, "\n");
}
i = (int)(mp - tmp->scr);
fprintf(was->fl, "%d nodes, %d memory\n", nodecnt, i);
fclose(was->fl);
}
/*
* Get a line from the current port.
* Handle disconnect and timeout.
*/
getit(tm)
int tm;
{
register short ctime;
ctime = port->ctime;
port->ctime = tm;
while(!getdat());
port->ctime = ctime;
switch(port->mode)
{
case timeout :
port->mode = remote;
return false;
case forced :
nodedone = true;
case discon :
distnc();
port->mode = idle;
return false;
default :
port->mode = remote;
parse();
return true;
}
}
#endif